﻿using AiQiuQuan.Sport.Core;
using AiQiuQuan.Sport.Model.Enums;
using AiQiuQuan.Sport.WebApi.Core;
using AiQiuQuan.Sport.WebApi.Entities;
using AiQiuQuan.Sport.WebApi.Repositories;
using Microsoft.EntityFrameworkCore;

namespace AiQiuQuan.Sport.WebApi.HangfireServices
{
    /// <summary>
    /// 场馆价格自动生成定时任务
    /// </summary>
    [ReccuringJobCron("0 0 2 * * ?")]
    public class VenueAutoCreatePricelHangfireService : IHangfireService
    {
        private readonly IVenueInfoRepository _venueInfoRepository;
        private readonly ISiteInfoRepository _siteInfoRepository;
        private readonly ISitePriceListRepository _sitePriceListRepository;
        private readonly ISpecialDateSettingRepository _specialDateSettingRepository;
        private readonly IBusinessHoursConfigRepository _usinessHoursConfigRepository;
        private readonly ISitePriceSpecialRuleRepository _sitePriceSpecialRuleRepository;

        /// <summary>
        /// ctor
        /// </summary>
        public VenueAutoCreatePricelHangfireService(
            IVenueInfoRepository venueInfoRepository,
            ISiteInfoRepository siteInfoRepository,
            ISitePriceListRepository sitePriceListRepository,
            ISpecialDateSettingRepository specialDateSettingRepository,
            IBusinessHoursConfigRepository usinessHoursConfigRepository,
            ISitePriceSpecialRuleRepository sitePriceSpecialRuleRepository)
        {
            _venueInfoRepository = venueInfoRepository;
            _siteInfoRepository = siteInfoRepository;
            _sitePriceListRepository = sitePriceListRepository;
            _specialDateSettingRepository = specialDateSettingRepository;
            _usinessHoursConfigRepository = usinessHoursConfigRepository;
            _sitePriceSpecialRuleRepository = sitePriceSpecialRuleRepository;
        }

        /// <summary>
        /// 执行
        /// </summary>
        public async Task ExecuteAsync()
        {
            var date = DateTime.Now.AddDays(7).Date;
            var dateStr = date.ToString("yyyy-MM-dd");
            var weekName = Tool.WeekName(date);
            //查询合作场馆
            var venuelist = await _venueInfoRepository.AsNoTracking().Where(x => x.VI_IsCooperate.Value).ToListAsync();

            foreach (var item in venuelist)
            {
                //查询今天是工作日还是休息日
                var dateModel = await _specialDateSettingRepository.AsNoTracking().FirstOrDefaultAsync(x => x.VenueInfoID == item.ID && x.Dates == date);
                var isWorkDay = dateModel != null ? dateModel.IsWorkDate.GetValueOrDefault() : Tool.IsWorkDay(date);

                //查询所有场地
                var sitelist = await _siteInfoRepository.AsNoTracking().Where(x => x.VenueInfoID == item.ID).ToListAsync();
                var list = new List<SitePriceList>();
                foreach (var sitemodel in sitelist)
                {
                    //场馆停止不生成 先检查是否已经生成过
                    if (sitemodel.SiteState == SiteStateEnum.StopIt
                        || await _sitePriceListRepository.AsNoTracking().AnyAsync(x => x.SiteInfoID == sitemodel.ID && x.SPL_Date == date))
                    {
                        continue;
                    }

                    //查询场地的营业时间配置
                    var hoursConfigList = await _usinessHoursConfigRepository.AsNoTracking().Where(x => x.SiteInfoID == sitemodel.ID)
                        .OrderBy(x => x.TimeSlotBegin).ToListAsync();
                    //查询是否存在日期段内特殊配置列表
                    var priceSpecialList = await _sitePriceSpecialRuleRepository.AsNoTracking()
                        .Where(x => x.VenueInfoID == item.ID
                                && x.SiteInfoID == sitemodel.ID
                                && x.SPSR_BeginTime <= date && x.SPSR_EndTime >= date
                                && x.SPSR_IsEffect.Value && x.SPSR_WeekNum == weekName).ToListAsync();

                    foreach (var hoursConfigModel in hoursConfigList)
                    {
                        var sitePriceListModel = new SitePriceList
                        {
                            VenueInfoID = sitemodel.VenueInfoID,
                            SiteInfoID = hoursConfigModel.SiteInfoID,
                            SPL_TimeSlot = hoursConfigModel.TimeSlotBegin,
                            SPL_TimeSlotEnd = hoursConfigModel.TimeSlotEnd,
                            SPL_CanUseIntegral = hoursConfigModel.WorkCanUseIntegral,
                            SPL_Date = date,
                            CreateTime = DateTime.Now,
                            CreateBy = "admin"
                        };

                        sitePriceListModel.SPL_Price = isWorkDay ? hoursConfigModel.WorkDefaultPrice : hoursConfigModel.VacaDefaultPrice;

                        var businessTimeS = TimeSpan.Parse(hoursConfigModel.TimeSlotBegin);
                        var businessTimeE = TimeSpan.Parse(hoursConfigModel.TimeSlotEnd);
                        if (priceSpecialList.Count > 0)
                        {
                            //筛选此时间段内是否有特殊配置
#pragma warning disable IDE0045 // 转换为条件表达式
                            if (priceSpecialList.Any(m => businessTimeS >= TimeSpan.Parse(m.SPSR_TimeSlotBegin) && businessTimeE <= TimeSpan.Parse(m.SPSR_TimeSlotEnd)))
#pragma warning restore IDE0045 // 转换为条件表达式
                            {
                                sitePriceListModel.SPL_State = VenuePriceStateEnum.PhysicalSales;
                            }
                            else
                            {
                                sitePriceListModel.SPL_State = sitemodel.SiteState == SiteStateEnum.Normal
                                    ? isWorkDay && hoursConfigModel.WorkDayCanUse
                                        ? VenuePriceStateEnum.CanChoice
                                        : !isWorkDay && hoursConfigModel.VacaDayCanUse ? VenuePriceStateEnum.CanChoice : VenuePriceStateEnum.CanNotChoice
                                    : VenuePriceStateEnum.CanNotChoice;
                            }
                        }
                        else
                        {
                            sitePriceListModel.SPL_State = sitemodel.SiteState == SiteStateEnum.Normal ? VenuePriceStateEnum.CanChoice : VenuePriceStateEnum.CanNotChoice;
                        }

                        list.Add(sitePriceListModel);
                    }
                }

                if (list.Any())
                {
                    await _sitePriceListRepository.BulkAddAsync(list);
                }
            }
        }
    }
}
